今天是介紹文本前處理的第三篇,我們已經介紹了四種文本前處理的方式,今天就來把最後兩種講完吧!
今天主要想聊的重點是如何將單詞還原成基本的形式,而這樣做的目的是把相近或重複的單詞統一,方便後續分析或完成其他任務。
首先是詞幹提取 ( Stemming ),顧名思義就是去掉單詞尾端的部分,只留下詞幹,舉例來說,eating
會變成 eat
,beautiful
會變成 beauti
。
這種做法的優點是運算簡單快速,然而也因為太過簡單,有時候反而會曲解了原本單詞的意思,比方說 organization
和 organize
都會變成 organ
,但是詞幹提取前後單詞的意思不一樣。
接下來是程式碼實作的部分,我們這次換成 NLTK 提供的 PorterStemmer:
from nltk.stem import PorterStemmer
def stemming(text):
porter = PorterStemmer()
result = []
for word in text:
result.append(porter.stem(word))
return result
tokens = stemming(['eating','beautiful','organization','organize','ate'])
print(tokens)
['eat', 'beauti', 'organ', 'organ', 'ate']
從這個例子可以看的出來,Stemming 只能對某些詞綴部分進行刪減,如果是遇到 ate
這種單詞就無法處理,不過接下來要介紹的 Lemmatization 就不一樣了。
詞型還原 ( Lemmatization ) 和詞幹提取不一樣的地方在於,它是對單詞進行型態上的分析,進而確認要對該單詞做什麼方式的處理,舉例來說,ate
會變成 eat
,better
會變成 well
。
詞型還原的好處在於它的準確性更高,不會把單詞變成一個字典上沒出現過的字,而且考量了該單詞的詞性和時態,在實際應用上效果更好,然而缺點是花的時間比詞幹提取還要多,因此通常會視任務內容來選擇要使用詞幹提取還是詞型還原。
以 NLTK 提供的 WordNetLemmatizer 為例,它在預設情況下設定的詞性為名詞,所以遇到其他詞性的單詞的話就要自己手動標註詞性:
import nltk
from nltk.stem import WordNetLemmatizer
nltk.download('wordnet')
lemmatizer = WordNetLemmatizer()
print("cars -> ", lemmatizer.lemmatize("cars"))
print("ate -> ", lemmatizer.lemmatize("ate", pos = 'v'))
cars -> car
ate -> eat
此外,我也有找到可以使用 NLTK 的工具來自動標註詞性的方法,雖然自己試過之後感覺還是會漏掉一些:
from nltk.stem import WordNetLemmatizer
from nltk import pos_tag
nltk.download('wordnet')
nltk.download('averaged_perceptron_tagger')
def lemmatization(wordlist):
lemmatizer = WordNetLemmatizer()
result = []
for word, tag in pos_tag(wordlist):
pos = tag[0].lower()
pos = 'n' if pos not in ['a', 'r', 'n', 'v'] else pos
result.append(lemmatizer.lemmatize(word, pos))
return result
tokens = lemmatization(['cars','ate','looked','better'])
print(tokens)
['car', 'eat', 'look', 'well']
詞性標註 ( POS ) 的概念剛好是明天想要聊的內容,今天先借來用一下。利用 NLTK 的 pos_tag 工具,我們可以先對每一個單詞標註上詞性,然後一併附給 lemmatizer 做詞形還原。
那麼來做個總結吧,通過剛剛的介紹,我們已經了解 Stemming 和 Lemmatization 的差別,以及各自的優點缺點。
在這三天的練習中,我們對於文本前處理的各種技術也有了不少的認識,這些技術可以根據不同的任務和場景互相搭配使用,但他們最終的目的都是要把一開始格式亂七八糟的文本整理好,方便後續任務進行。
接下來幾天的規劃應該會是如何對單詞和句子做分析,像是 POS、NER、Parsing 之類的,然後再進行下一個篇章。
推薦文章
https://www.nltk.org/howto/stem.html
https://www.nltk.org/api/nltk.stem.wordnet.html